<template>
	<view :class="['input-combination', `input-combination--${size}`]">
		<view :class="['combination', 'left-combination']" v-if="combinationConfig.isShow && combinationConfig.position === 'left' || combinationConfig.position === 'ends'">
			<slot name="left">
				<button>{{ combinationConfig.buttonText }}</button>
			</slot>
		</view>
		<view :class="['input-container', `input-container--${combinationConfig.position}`]">
			<input
				:value="inputValue"
				:class="[
					'v-input',
					{ 'v-input--disabled': disabled },
					{ 'input-focused': focused },
					`v-input--border--${borderModel}`,
					`v-input--right--combination--${combinationConfig.position}`
				]"
				:placeholder="currentPlaceholder"
				:maxlength="maxlength || undefined"
				:disabled="disabled"
				:type="type"
				:focus="autoFocus"
				@input="handleInput"
				@focus="handleFocus"
				@blur="handleBlur"
				@confirm="handleConfirm"
			/>
			<view v-if="showCounter && maxlength" class="input-counter">{{ currentLength }}/{{ maxlength }}</view>
		</view>
		<view :class="['combination', 'right-combination']" v-if="combinationConfig.isShow && combinationConfig.position === 'right' || combinationConfig.position === 'ends'">
			<slot name="right">
				<button>{{ combinationConfig.buttonText }}</button>
			</slot>
		</view>
	</view>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted, inject } from 'vue';

interface CombinationConfig {
	isShow: Boolean;
	position: String;
	buttonText: String;
}

/**
 * v-input 输入框
 * value 双向绑定值
 * size 文本框大小             	默认值:medium   可选值small小、medium中、large大
 * placeholder 提示语 字符串、数组
 * placeholderTimeNumber 更换提示词耗时 			默认:8秒
 * maxlength 最大输入值 			默认:null 		不限制
 * disabled 是否禁用           	默认:false   	可选值:true禁用 false不禁用
 * type 文本框类型             	默认:text    	可选值:text、password‌、number‌‌
 * showCounter 是否显示统计文字 	默认:false  		可选值:true显示统计文字 false不显示统计文字
 * borderModel 边框模式         	默认:all    		可选值:all普通边框 nont无边框模式 bottom底部边框模式 top上边框模式 left左边框模式 right右边框模式 ends左右两端边框模式 up-down上下边框模式
 * combinationConfig 组合组件
 * 		isShow:是否显示插槽 默认值:false  		可选值:true显示 false不显示
 * 		position:组合组件显示位置 默认值:default	可选值:right右边 left左边 ends两端
 * 		插槽right、left
 * 相关事件:focus、blur、confirm
 */
const props = defineProps({
	value: {
		type: String,
		default: '',
		required: true
	},
	size: {
		type: String,
		default: 'medium',
		validator: (value: string) => ['small', 'medium', 'large'].includes(value)
	},
	placeholder: {
		type: [String, Array],
		default: ''
	},
	placeholderTimeNumber: {
		type: Number,
		default: 8000
	},
	maxlength: {
		type: Number,
		default: null
	},
	disabled: {
		type: Boolean,
		default: false
	},
	type: {
		type: String,
		default: 'text',
		validator: (value: string) => ['text', 'password', 'number'].includes(value)
	},
	showCounter: {
		type: Boolean,
		default: false
	},
	borderModel: {
		type: String,
		default: 'all'
	},
	combinationConfig: {
		type: Object as () => CombinationConfig,
		default: {
			isShow: false,
			position: 'default',
			buttonText: ''
		}
	},
	inputTextPosition: {
		type: String,
		default: 'left'
	},
	autoFocus: {
	  type: Boolean,
	  default: false
	}
});

const emit = defineEmits(['update:value', 'input', 'focus', 'blur', 'confirm']);

const config = inject<any>('config');
const inputValue = ref(props.value);
const focused = ref(false);
const currentLength = ref(props.value.length);
const currentPlaceholder = ref('');
const placeholderIndex = ref(0);
let placeholderInterval: NodeJS.Timeout | null = null;

watch(
	() => props.value,
	(newVal) => {
		inputValue.value = newVal;
		currentLength.value = newVal.length;
	}
);

watch(
	() => props.placeholder,
	(newVal) => {
		if (Array.isArray(newVal) && newVal.length > 0) {
			currentPlaceholder.value = newVal[0];
			placeholderIndex.value = 0;
		} else if (typeof newVal === 'string') {
			currentPlaceholder.value = newVal;
		}
	},
	{ immediate: true }
);

onMounted(() => {
	if (Array.isArray(props.placeholder) && props.placeholder.length > 1) {
		startPlaceholderRotation();
	}
});

onUnmounted(() => {
	if (placeholderInterval) {
		clearInterval(placeholderInterval);
		placeholderInterval = null;
	}
});

const startPlaceholderRotation = () => {
	placeholderInterval = setInterval(() => {
		placeholderIndex.value = (placeholderIndex.value + 1) % props.placeholder.length;
		currentPlaceholder.value = props.placeholder[placeholderIndex.value];
	}, props.placeholderTimeNumber);
};

const handleInput = (e: any) => {
	const value = e.detail.value;
	inputValue.value = value;
	currentLength.value = value.length;
	emit('update:value', value);
	emit('input', value);
};

const handleFocus = (e: any) => {
	focused.value = true;
	emit('focus', e);
};

const handleBlur = (e: any) => {
	focused.value = false;
	emit('blur', e);
};

//回车搜索
const handleConfirm = (e: any) => {
	if (e.detail.value.trim() === '' && Array.isArray(props.placeholder) && currentPlaceholder.value) {
		emit('confirm', currentPlaceholder.value, e);
	} else {
		emit('confirm', e.detail.value, e);
	}
};
</script>

<style lang="scss" scoped>
.input-combination {
	display: flex;

	&--small {
		height: 50rpx;
	}

	&--medium {
		height: 60rpx;
	}

	&--large {
		height: 70rpx;
	}

	.input-container {
		width: 100%;
		height: 100%;
		position: relative;

		&--default {
			width: 100%;
		}

		&--right,
		&--left {
			width: 75%;
		}
		&--ends {
			width: 50%;
		}

		.v-input {
			width: 100%;
			height: 100%;
			min-height: 45rpx;
			box-sizing: border-box;
			background-color: #fff;
			font-size: v-bind("config.fontSize.mediumText");
			line-height: 1.5;
			transition: border-color 0.3s;
			text-align: v-bind('props.inputTextPosition');

			::v-deep .uni-input-wrapper {
				width: 92% !important;
				margin-left: 3%;
			}

			&--border--all {
				border: 1px solid v-bind('config.border.color');
				border-radius: 6rpx;

				&.input-focused {
					border-color: v-bind('config.border.default');
					box-shadow: v-bind("config.VInput.boxShadow");
				}
			}

			&--border--none {
				border: none;
			}

			&--border--bottom {
				border-bottom: 1rpx solid v-bind('config.border.color');
			}

			&--border--top {
				border-top: 1rpx solid v-bind('config.border.color');
			}

			&--border--left {
				border-left: 1rpx solid v-bind('config.border.color');
			}

			&--border--right {
				border-right: 1rpx solid v-bind('config.border.color');
			}

			&--border--ends {
				border-left: 1rpx solid v-bind('config.border.color');
				border-right: 1rpx solid v-bind('config.border.color');
			}

			&--border--up-down {
				border-top: 1rpx solid v-bind('config.border.color');
				border-bottom: 1rpx solid v-bind('config.border.color');
			}

			&--right--combination--right {
				border-right: none;
				border-top-right-radius: 0;
				border-bottom-right-radius: 0;
			}

			&--right--combination--left {
				border-left: none;
				border-top-left-radius: 0;
				border-bottom-left-radius: 0;
			}

			&--right--combination--ends {
				border-right: none;
				border-top-right-radius: 0;
				border-bottom-right-radius: 0;

				border-left: none;
				border-top-left-radius: 0;
				border-bottom-left-radius: 0;
			}

			&--disabled {
				opacity: v-bind('config.opacity.disabled');
				background-color: v-bind('config.backgroundColor.disabled');
				color: v-bind('config.fontColor.text');
			}
		}
		.input-counter {
			position: absolute;
			bottom: 8rpx;
			right: 8rpx;
			font-size: v-bind("config.fontSize.smallText");
			color: v-bind('config.fontColor.text');
		}
	}

	.combination {
		width: 25%;
		height: 100%;
		button {
			width: 100%;
			height: 100%;
			display: flex;
			align-items: center;
			justify-content: center;
			background-color: v-bind('config.backgroundColor.default');
			color: v-bind('config.fontColor.reversal');
			font-size: v-bind("config.fontSize.mediumText");
		}
	}

	.left-combination button {
		border-bottom-right-radius: 0;
		border-top-right-radius: 0;
	}

	.right-combination button {
		border-bottom-left-radius: 0;
		border-top-left-radius: 0;
	}
}
</style>
